﻿using System;
using System.Data;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using PengSW.NotifyPropertyChanged;
using PengSW.ObservableCollectionHelper;
using PengSW.XmlHelper;
using static PengSW.RuntimeLog.RL;

namespace PengSW.XmlImport
{
    public class ImportRule : NotifyPropertyChangedObject, IXmlSeriable, ICloneable
    {
        public ImportRule()
        {
            ReplaceRules = new ObservableCollectionEx<ReplaceRule>();
            TableDefine = new TableDefine(this);
        }

        public ObservableCollectionEx<ReplaceRule> ReplaceRules { get; } 
        public TableDefine TableDefine { get; }

        public void ReadFromXml(XElement aXElement)
        {
            if (aXElement == null) return;

            // ReplaceRules.Clear();
            if (aXElement.Element(nameof(ReplaceRules))?.Elements(nameof(ReplaceRule)) != null)
                foreach (XElement aChildXElement in aXElement.Element(nameof(ReplaceRules)).Elements(nameof(ReplaceRule)))
                {
                    ReplaceRule aReplaceRule = new ReplaceRule(this);
                    aReplaceRule.ReadFromXml(aChildXElement);
                    ReplaceRules.Add(aReplaceRule);
                }

            TableDefine.ReadFromXml(aXElement.Element(nameof(TableDefine)));
        }

        public XElement CreateXElement(string aXmlNodeName)
        {
            return new XElement(aXmlNodeName,
                new XElement(nameof(ReplaceRules), from r in ReplaceRules select r.CreateXElement(nameof(ReplaceRule))),
                TableDefine.CreateXElement(nameof(TableDefine)));
        }

        public DataTable Import(XElement aXElement)
        {
            if (aXElement == null) return null;
            return TableDefine.Import(aXElement);
        }

        public void CreateDefaultImportRule(XElement aXElement, string aTableName)
        {
            XElement aTableXElement = string.IsNullOrWhiteSpace(aTableName) ? aXElement.Element("Table") : (from r in aXElement.Elements("Table") where r.Attribute("Id")?.Value == aTableName select r).FirstOrDefault();
            if (aTableXElement == null) throw new ApplicationException("没有找到可用的Table节！");

            TableDefine.SourceTable = aTableName;
            RecordDefine aRecordDefine = new RecordDefine(TableDefine);
            foreach (XElement aFieldXElement in aTableXElement.XPathSelectElements("Record/*"))
            {
                string aFieldName = aFieldXElement.Name.LocalName;
                if (aRecordDefine.FieldDefines.FirstOrDefault(r => r.SourceField == aFieldName) == null)
                {
                    aRecordDefine.FieldDefines.Add(new FieldDefine(aRecordDefine) { SourceField = aFieldName, TargetField = aFieldName });
                }
            }
            TableDefine.RecordDefines.Add(aRecordDefine);
        }

        public object Clone()
        {
            ImportRule aImportRule = new ImportRule();
            aImportRule.ReadFromXml(CreateXElement("ImportRule"));
            return aImportRule;
        }
    }
}
